package com.alibaba.citrus.cr.platform.enhance.facade.service.diff.activity;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import com.alibaba.citrus.cr.common.annotation.FunctionInvoker;
import com.alibaba.citrus.cr.common.annotation.ProcessInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.platform.enhance.facade.service.diff.common.constant.DiffTypeEnum;
import com.alibaba.citrus.cr.platform.enhance.repository.ActivityQueryRepository;
import com.alibaba.citrus.cr.platform.enhance.repository.DiffErrorRepository;
import com.alibaba.citrus.cr.platform.enhance.repository.model.diff.activity.QueryActivityUseRecordParam;
import com.alibaba.citrus.cr.platform.enhance.repository.model.diff.common.DiffErrorDTO;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.lattice2.epoch.sdk.model.Result;

import com.epoch.app.crplatformenhance.activitytotalcountdiffcheck.service.ActivityTotalCountDiffCheckService;
import com.epoch.app.crplatformenhance.model.dto.ActivityDiffCheckRequest;
import com.epoch.app.crpricecenter.sdo.ActivityTermSDO;
import com.epoch.app.crpricecenter.sdo.ActivityUseRecordRelationSDO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

/**
 * @author: qiaojiange
 * @create: 2022/02/15
 * @Description 活动总数对账
 */
@Service
@Primary
public class ActivityTotalCountDiffCheckServiceImpl implements ActivityTotalCountDiffCheckService {
    /**
     * 日志
     */
    private Log log = Log.getLogger(ActivityDiffCheckServiceImpl.class);
    @Resource
    private ActivityQueryRepository activityQueryRepository;

    @Resource
    private ApplicationContext applicationContext;

    @Resource
    private DiffErrorRepository diffErrorRepository;

    @FunctionInvoker
    @Override
    public Result<String> totalCountDiffCheck(ActivityDiffCheckRequest request) {
        // 定时任务（ScheduleX ），按照修改时间搜索变更的活动term。---》 DAO,按modify时间升序，可以支持分页查询 20。
        // 存到对账记录表中 --->暂时不做
        // 从活动 term中的提取数据 b1
        // 和标准模板对比
        // 获取该 term的所有活动使用记录列表
        // 提取活动使用记录列表中的占用金额和数量
        // 累加活动使用记录列表中的占用金额和数量 b2
        // 对比b1 和 b2 --->解决错的问题 ---》峥嵘

        checkParam(request);
        Result<List<ActivityTermSDO>> termListResult = activityQueryRepository.queryModifiedActivityTermList(request);
        if (termListResult != null && CollectionUtils.isNotEmpty(termListResult.getResult())) {
            int total = termListResult.getTotal();
            boolean isFirst = true;
            while (total > 0 && request.getStart() < total) {
                if (!isFirst) {
                    termListResult = activityQueryRepository.queryModifiedActivityTermList(request);
                } else {
                    isFirst = false;
                }

                if (termListResult != null && CollectionUtils.isNotEmpty(termListResult.getResult())) {
                    List<DiffErrorDTO> diffErrorListResult = new ArrayList<>();
                    for (ActivityTermSDO termSDO : termListResult.getResult()) {
                        List<DiffErrorDTO> diffErrorList = applicationContext.getBean(ActivityTotalCountDiffCheckServiceImpl.class).doDiff(termSDO);
                        diffErrorListResult.addAll(diffErrorList);
                    }
                    if (CollectionUtils.isNotEmpty(diffErrorListResult)) {
                        diffErrorRepository.batchSaveDiffErrorList(diffErrorListResult);
                    }
                }
                request.setStart(request.getStart() + request.getLimit());
            }
            return Result.success("对比完成");
        }
        return Result.fail("", "没有查询到可用的活动 term列表数据");
    }

    /**
     * 校验参数
     * @param request 活动对账请求
     */
    private void checkParam(ActivityDiffCheckRequest request) {
        if (request == null) {
            throw new FacadeException("OTS-13-001-00-16-014");
        }

        if (request.getLimit() == null || request.getLimit() <= 0) {
            throw new FacadeException("OTS-13-001-00-16-015");
        }
        if (request.getStart() == null || request.getStart() < 0) {
            throw new FacadeException("OTS-13-001-00-16-016");
        }

        if (request.getStartDiffDate() == null) {
            throw new FacadeException("OTS-13-001-00-16-017");
        }

        if (request.getEndDiffDate() == null) {
            throw new FacadeException("OTS-13-001-00-16-018");
        }
    }

    @ProcessInvoker
    public List<DiffErrorDTO> doDiff(ActivityTermSDO termSDO) {
//        使用模板还是不使用模板呢？--->使用模板进行对比比较清晰
//        不使用模板这里的业务本身就不够复杂，可以直接进行对比 ---》选择不使用模板

        //解析出已经占用的总费用、总数量
        QueryActivityUseRecordParam param = new QueryActivityUseRecordParam();
        param.setActivityId(termSDO.getActivityId());
        param.setActivityTermId(termSDO.getActivityTermId());
        param.setStatus(1);
        param.setStart(0);
        param.setLimit(30);

        Long occupyFeeSum = 0L;
        Long occupyQuantitySum = 0L;
        //根据活动 id, 活动 termId 查询活动使用记录列表，进行循环累加，计算出总费用和总数量
        Result<List<ActivityUseRecordRelationSDO>> recordList = activityQueryRepository.queryActivityUseRecordListByActivityTermId(param);
        if (recordList != null && recordList.isSuccess()) {
            int total = recordList.getTotal();
            boolean isFirst = true;
            while (param.getStart() < total) {
                if (!isFirst) {
                    recordList = activityQueryRepository.queryActivityUseRecordListByActivityTermId(param);
                } else {
                    isFirst = false;
                }
                if (recordList != null && recordList.isSuccess() && CollectionUtils.isNotEmpty(recordList.getResult())) {
                    for (ActivityUseRecordRelationSDO sdo : recordList.getResult()) {
                        occupyQuantitySum += sdo.getItemQuantity();
                        occupyFeeSum += sdo.getActivityOccupyFee();
                    }
                }
                param.setStart(param.getStart() + param.getLimit());
            }

        }

        List<DiffErrorDTO> result = new ArrayList<>();
        if (!termSDO.getActivityOccupyFee().equals(occupyFeeSum)) {

            //埋点
            log.error("ActivityTotalCountDiffCheckServiceImpl#activityTotalCountDiffCheck_fail");
            DiffErrorDTO diffErrorDTO = DiffErrorDTO.builder()
                    .diffType(DiffTypeEnum.ACTIVITY_TOTAL_COUNT_DIFF_CHECK.getDiffType())
                    .diffDesc(DiffTypeEnum.ACTIVITY_TOTAL_COUNT_DIFF_CHECK.getDiffDesc())
                    .diffData1(termSDO.getActivityOccupyFee().toString())
                    .diffData2(occupyFeeSum.toString()).result("活动总数对账,占用金额(activityOccupyFee)不一致！")
                    .activityId(termSDO.getActivityId())
                    .activityTermId(termSDO.getActivityTermId()).build();
            result.add(diffErrorDTO);
        }

        Long termOccupyQuantitySum = new Long(termSDO.getActivityOccupyQuantity());
        if (!termOccupyQuantitySum.equals(occupyQuantitySum)) {
            //埋点
            log.error("ActivityTotalCountDiffCheckServiceImpl#activityTotalCountDiffCheck_fail");
            DiffErrorDTO diffErrorDTO = DiffErrorDTO.builder()
                    .diffType(DiffTypeEnum.ACTIVITY_TOTAL_COUNT_DIFF_CHECK.getDiffType())
                    .diffDesc(DiffTypeEnum.ACTIVITY_TOTAL_COUNT_DIFF_CHECK.getDiffDesc())
                    .diffData1(termSDO.getActivityOccupyQuantity().toString())
                    .diffData2(occupyQuantitySum.toString()).diffDesc("活动总数对账,占用数量(activityOccupyQuantity)不一致！")
                    .activityId(termSDO.getActivityId())
                    .activityTermId(termSDO.getActivityTermId()).build();
            result.add(diffErrorDTO);
        }

        return result;
    }
}
